package ee.rawre.tafayc.util;


import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

public class TypingStatus extends FlowPanel {
	
   private int maxcount, count=0, words=0, errors;
   private long startTime, time;
   private static boolean finish;
   private CookieManager cookieManager;
	
   
   /**
    * Measures typing speed and accuracy and saves them locally for comparsion
    * 
    * @param cookieManager something that handles cookies
    */
   public TypingStatus(CookieManager cookieManager) {
      this.cookieManager = cookieManager;
      setText("This is a test!");
   }

   
   
   /**
	 * Starts the stopwatch
	 */
	public void start() {
      setFinish(false);
	   startTime = System.currentTimeMillis();
	   errors = 0;
	}
	
	
	
	/**
	 * Stops the stopwatch
	 */
	public void stop() {
	   int cpm, wpm;
	   time = System.currentTimeMillis()-startTime;
	   cpm = (int) ((float)maxcount/((float)time/1000/60)); // chars per minute
	   wpm = (int)((float)words/((float)time/1000/60));     // words per minute
      cookieManager.setCookie(maxcount, words, cpm, wpm, errors);
      RootPanel.get("resultLabelContainer").add(new Label(time + " milliseconds with " + 
            errors + " errors and speed " + cpm + " cpm / " + wpm + " wpm"));
   }
	
	
	
	/**
	 * Sets the text which is going to be typed in
	 * 
	 * @param text
	 */
	public void setText(String text) {
	   String cString;
	   clear();   // removes old text
	   maxcount = text.length();
		char[] chars = text.toCharArray();
		for (char c : chars) {
		   cString = Character.toString(c);
			add(new Span(cString));
			if (cString.equals(" ")) words++;
		}
		words++;
	}

	
	
	/**
	 * Handles multiple characters in one input check sequence
	 * 
	 * @param s multiple characters as String
	 * @return <code>true</code> if the competition has ended
	 */
	public boolean keyPresses(String s) {
	   if (s.length() > 0.5*maxcount) {   // tries to avoid cheating
   	   RootPanel.get("resultLabelContainer").clear();
   	   RootPanel.get("resultLabelContainer").add(new Label("Sorry, start again"));
   	   setFinish(true);    //
   	   return finish;      // ends the competition
	   }
      for (char c : s.toCharArray()) {
         keyPress(c);   // pass chars for comparing
      }
      return finish;
   }
	
	
	/**
	 * Handles single character at a time
	 * 
	 * @param c entered char
	 * @return <code>true</code> if the time has been stopped
	 */
   public boolean keyPress(char c) {
      if (count < maxcount) {
         if (getWidget(count).getElement().getInnerText().charAt(0) == c) {
            getWidget(count).getElement().setClassName("ok");
            count++;
         } else {
            getWidget(count).getElement().setClassName("notok");
            count++;
            errors++;
         }
         if (!finish && count == maxcount) {
            stop();
            setFinish(true);
         }
      }
      if (count == 1) {
         start();
         RootPanel.get("resultLabelContainer").clear();
      }
      return finish;
   }
   

   
   
   /**
    * Takes one character back
    * 
    * @param curLenght current cursor position
    */
   public void backspacePress(int curLenght) {
      if (curLenght == 0) {
         count = 0;
         for (int i=0; i<maxcount; i++) {
            getWidget(i).getElement().setClassName("");
         }
      } else if (count>0 && curLenght<maxcount) {
         count--;
         if(getWidget(count).getElement().getClassName().equals("notok")) 
            errors--;   // if the removed char was incorrect, the error counter gets modified too
         getWidget(count).getElement().setClassName("");
      }
   }
   
   
   
   public static boolean isFinish() {
      return finish;
   }

   public static void setFinish(boolean finish) {
      TypingStatus.finish = finish;
   }
}
